<?php

namespace App\Util;

/**
 * Created by PhpStorm.
 * User: Huyang
 * Date: 2016/10/12
 * Time: 10:59
 */
class Helper
{

    public static function dataToKey($data) {
        $result = [];
        foreach ($data as $key => $val) {
            $tmp = [];
            $tmp['name'] = $val;
            $tmp['id'] = $key;
            $result[] = $tmp;
        }
        return $result;
    }

    public static function p($content) {
        $search = ["\r\n","\r","\n"];
        $replace = ['</p><p>','</p><p>','</p><p>'];
        $content = str_replace($search, $replace, $content);
        return '<p>'.$content.'</p>';
    }

    /**
     * 订单日志
     * @param        $data
     * @param string $keyName
     * @return array
     */
    public static function log($data, $keyName = 'content') {
        $temp = $return = [];
        foreach ($data as $key => $item) {
            $date = substr($item['created_at'], 0, 10);
            if (in_array($date, $temp)) {
                $return[$key]['date'] = '';
            } else {
                $return[$key]['date'] = $date;
            }
            $return[$key]['hour'] = substr($item['created_at'], -8, 8);
            $return[$key][$keyName] = str_replace(array('[]',' '), '', $item[$keyName]);
            $temp[] = $date;
        }
        return $return;
    }

    /**
     * @param $number
     * @param $unit
     * @return int
     */
    public static function second($number, $unit) {

        $sec = 0;

        switch ($unit) {
            case 1:
                $sec = $number * 60;
                break;
            case 2:
                $sec = $number * 3600;
                break;
            case 3:
                $sec = $number * 86400;
                break;
            default:
                break;
        }

        return $sec;

    }

    /**
     * 物流
     * @param $data
     * @return array
     */
    public static function trans($data) {
        $temp = $return = [];
        foreach ($data as $key => $item) {
            $date = substr($item->time, 0, 10);
            if (in_array($date, $temp)) {
                $return[$key]['date'] = '';
            } else {
                $return[$key]['date'] = substr($date, -5,5);
            }
            $return[$key]['hour'] = substr($item->time, -8, 8);
            $return[$key]['status'] = $item->context;
            $temp[] = $date;
        }
        return $return;
    }

    /**
     * 判断是否为Json字符串
     * @param $string
     * @return bool
     */
    public static function json($string) {
        if (is_array($string)) {
            return false;
        }
        @json_decode($string);
        return (json_last_error() == JSON_ERROR_NONE);
    }

    /**
     * 位运算,返回结果
     * $m 用户自己拥有的权限
     * $s 需要进行比较的权限值,比如,读,写,删除
     */
    public static function wys($m, $s) {
        return $m & $s;
    }

    /**
     * 去掉width 和 height标签
     * @param $content
     * @return mixed
     */
    public static function clearImgWidthHeight($content){
        preg_match_all('/<[img|IMG].*?src=[\'|"](.*?(?:[\.gif|\.jpg|\.png\.bmp\w_\d]))[\'|"].*?[\/]?>/', $content, $images);
        if(!empty($images)) {
            foreach($images[0] as $index => $value){
                $new_img = preg_replace('/(width|height)="\d*"\s/', "", $images[0][$index]);
                $content = str_replace($images[0][$index], $new_img, $content);
            }
        }
        return $content;
    }

    /**
     *@ 根据id返回id所在目录，避免所有文件都存在同一目录导致日后手动维护的不便
     */
    public static function pathId($id) {
        return round($id / 500) . '/' . $id;
    }

    /**
     * 检测是否是一个日期格式
     *
     * @param string 2012-03-01
     * @return bool
     */
    public static function vdate($date) {
        if (preg_match('/[\d]{4}-[\d]{2}-[\d]{2}/', $date) && $date != '0000-00-00') {
            return True;
        }
        return False;
    }

    /**
     * 单位转换,分转为元
     * @param $money
     * @return mixed
     */
    public static function amount($money) {
        return sprintf("%.2f", round($money,2));
    }

    /**
     * 单位转换,分转为元
     * @param $money
     * @return mixed
     */
    public static function centToYuan($money) {
        return round($money/100,2);
    }

    /**
     * 单位转换,元转为分
     * @param $money
     * @return mixed
     */
    public static function yuanToCent($money) {
        return $money*100;
    }

    /**
     * 生成html的select标签
     * $option 下拉数组,数组的key为值,value为文本
     * $select_id 默认选中的key
     * $select_non 是否有提示
     * $tag_name,标签名称
     * $tag_id,标签ID
     * $onchange,标签onchange事件
     * $tag_css,标签CSS名称
     * $style,标签CSS样式
     */
    /**
     * @param        $option
     * @param        $select_id
     * @param string $select_non
     * @param string $tag_name
     * @param string $tag_id
     * @param string $onchange
     * @param string $tag_css
     * @param string $style
     * @param bool   $disabled
     * @return string
     */
    public static function selectHtml($option, $select_id, $select_non = '', $tag_name = '', $tag_id = '', $onchange = '', $tag_css = '', $style = '', $disabled = False) {
        $disabled = $disabled ? ' disabled="disabled"' : '';
        $tag_css = $tag_css ? ' class="'.$tag_css.'"' : '';
        $style = $style ? ' style="'.$style.'"' : '';
        $required = '';
        if (strpos($onchange, 'required') !== false) {
            $onchange = str_replace('required', '', $onchange);
            $required = ' lay-verify="required"';
        }
        $onchange = $onchange ? ' onchange="'.$onchange.'"' : '';
        $return = '<select lay-filter="'.$tag_name.'" name="'.$tag_name.'" id="'.$tag_id.'"'.$required.$onchange.$tag_css.$style.$disabled.'>';
        if ($select_non) {
            $return .= '<option value="">'.$select_non.'</option>';
        }
        foreach ($option as $key => $val) {
            if (strlen($val) > 3) {
                $val = strip_tags($val);
            }
            if ($select_id !== $key) {
                $return .= '<option value="'.$key.'">'.$val.'</option>';
            } else {
                $return .= '<option value="'.$key.'" selected="selected">'.$val.'</option>';
            }
        }
        $return .= '</select>';
        return $return;
    }


    /**
     * 生成html的radio标签
     * @param        $radios 一个数组，数组的key为radio的值，key对应的值为该radio的文字描述，
     * @param        $default_val 如果为数组的其中一个key，那么这个key默认为被选中状态
     * @param        $tag_name 标签的name属性值
     * @param bool   $key_value
     * @param string $onclick 该radio被单击时所触发的js脚本
     * @param bool   $default_key
     * @param bool   $disabled
     * <label><input type="radio" disabled="" checked="" value="option2"> <i></i> 选项3（选中并禁用）</label>
     * @return string
     */
    public static function radioHtml ($radios, $default_val, $tag_name, $key_value = true, $onclick = '', $default_key = true, $disabled = False) {

        $disabled = $disabled ? ' disabled="disabled" ' : '';
        $tpl = $return = '';
        if ($onclick) {
            $tpl .= ' onclick="return '.$onclick.';"';
        }
        $tpl .= $disabled.'/> <i></i> ';
        $i = 1;
        if ($key_value === true) {
            if ($default_key === true) {
                foreach ($radios as $key => $val) {
                    $val = '&nbsp;'.strip_tags($val);
                    if ($key != $default_val) {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" value="'.$key.'"'.$tpl.$val.'</label>';
                    } else {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" value="'.$key.'" checked="checked"'.$tpl.$val.'</label>';
                    }
                    $i++;
                }
            } else {
                foreach ($radios as $key => $val) {
                    $val = '&nbsp;'.strip_tags($val);
                    if ($val != $default_val) {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" value="'.$key.'"'.$tpl.$val.'</label>';
                    } else {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" value="'.$key.'" checked="checked"'.$tpl.$val.'</label>';
                    }
                    $i++;
                }

            }
        } else {
            if ($default_key === true) {
                foreach ($radios as $key => $val) {
                    $val = '&nbsp;'.strip_tags($val);
                    if ($key != $default_val) {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" value="'.$val.'"'.$tpl.$val.'</label>';
                    } else {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" value="'.$val.'" checked="checked"'.$tpl.$val.'</label>';
                    }
                    $i++;
                }
            } else {
                foreach ($radios as $key => $val) {
                    $val = '&nbsp;'.strip_tags($val);
                    if ($val != $default_val) {
                        $return .= '<label><input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" value="'.$val.'"'.$tpl.$val.'</label>';
                    } else {
                        $return .= '<label><input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" value="'.$val.'" checked="checked"'.$tpl.$val.'</label>';
                    }
                    $i++;
                }

            }
        }
        return $return;
    }

    /**
     * 生成html的radio标签
     * @param        $radios 一个数组，数组的key为radio的值，key对应的值为该radio的文字描述，
     * @param        $default_val 如果为数组的其中一个key，那么这个key默认为被选中状态
     * @param        $tag_name 标签的name属性值
     * @param bool   $key_value
     * @param string $onclick 该radio被单击时所触发的js脚本
     * @param bool   $default_key
     * @param bool   $disabled
     * <label><input type="radio" disabled="" checked="" value="option2"> <i></i> 选项3（选中并禁用）</label>
     * @return string
     */
    public static function radioLayUi ($radios, $default_val, $tag_name, $key_value = true, $onclick = '', $default_key = true, $disabled = False) {

        $disabled = $disabled ? ' disabled="disabled" ' : '';
        $tpl = $return = '';
        if ($onclick) {
            $tpl .= ' onclick="return '.$onclick.';"';
        }
        $tpl .= $disabled.'/>';
        $i = 1;
        if ($key_value === true) {
            if ($default_key === true) {
                foreach ($radios as $key => $val) {
                    $val = strip_tags($val);
                    if ($key != $default_val) {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" title="'.$val.'" value="'.$key.'"'.$tpl;
                    } else {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" title="'.$val.'" value="'.$key.'" checked="checked"'.$tpl;
                    }
                    $i++;
                }
            } else {
                foreach ($radios as $key => $val) {
                    $val = strip_tags($val);
                    if ($val != $default_val) {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" title="'.$val.'" value="'.$key.'"'.$tpl;
                    } else {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" title="'.$val.'" value="'.$key.'" checked="checked"'.$tpl;
                    }
                    $i++;
                }

            }
        } else {
            if ($default_key === true) {
                foreach ($radios as $key => $val) {
                    $val = strip_tags($val);
                    if ($key != $default_val) {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" title="'.$val.'" value="'.$val.'"'.$tpl;
                    } else {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" title="'.$val.'" value="'.$val.'" checked="checked"'.$tpl;
                    }
                    $i++;
                }
            } else {
                foreach ($radios as $key => $val) {
                    $val = strip_tags($val);
                    if ($val != $default_val) {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" title="'.$val.'" value="'.$val.'"'.$tpl;
                    } else {
                        $return .= '<input type="radio" name="'.$tag_name.'" id="'.$tag_name.$i.'" title="'.$val.'" value="'.$val.'" checked="checked"'.$tpl;
                    }
                    $i++;
                }

            }
        }
        return $return;
    }

    /**
     * htmlCheckbox
     * 动态生成checkbox多选框
     * htmlCheckbox -> 数组，循环该数组生成多选框
     * tag_name -> name属性值
     * val_value -> 是否用数组的key做为value属性值, false 则用key来做value属性值, true则用数组的值作为value属性值,默认用数组值做value属性值
     * onclick -> 单击checkbox框触发什么函数 可为空
     * tagcss -> css名称 可为空
     * style -> style值, 可为空
     * <div class="checkbox i-checks">
     *      <label><input type="checkbox" value="" disabled="" checked=""> <i></i> 选项3（选中并禁用）</label>
     * </div>
     */
    public static function checkboxHtml ($checkboxArr, $tag_name, $val_value = true, $onclick = '', $tag_css = '', $tag_style = '', $checkedArr = Array(), $new_line = 10) {

        $checked = $tpl = $return = '';

        if ($onclick) {
            $tpl .= ' onclick="return '.$onclick.';"';
        }
        if ($tag_css) {
            $tpl .= ' class="'.$tag_css.'"';
        }
        if ($tag_style) {
            $tpl .= ' style="'.$tag_style.'"';
        }
        $tpl .= '/>';
        $i = 1;
        if ($val_value === true) {
            foreach ($checkboxArr as $key => $val) {
                $val = strip_tags($val);
                if (in_array($val, $checkedArr)) {
                    $checked = 'checked="checked"';
                } else {
                    $checked = '';
                }
                $return .= '<input type="checkbox" name="'.$tag_name.'[]" id="'.$tag_name.$i.'" '.$checked.' value="'.$val.'" '.$tpl.'&nbsp<label for="'.$tag_name.$i.'">'.$val.'</label>&nbsp;&nbsp;';
                if ($i % $new_line == 0) {
                    $return .= '<br />';
                }
                $i++;
            }
        } else {
            foreach ($checkboxArr as $key => $val) {
                $val = strip_tags($val);
                if (in_array($key, $checkedArr)) {
                    $checked = 'checked="checked"';
                } else {
                    $checked = '';
                }
                $return .= '<input type="checkbox" name="'.$tag_name.'['.$key.']" id="'.$tag_name.$key.'" '.$checked.' value="'.$key.'" '.$tpl.'&nbsp<label for="'.$tag_name.$key.'">'.$val.'</label>&nbsp;&nbsp;';
                if ($i % $new_line == 0) {
                    $return .= '<br />';
                }
                $i++;
            }
        }
        return $return;
    }

    /**
     * htmlCheckbox
     * 动态生成checkbox多选框
     * htmlCheckbox -> 数组，循环该数组生成多选框
     * tag_name -> name属性值
     * val_value -> 是否用数组的key做为value属性值, false 则用key来做value属性值, true则用数组的值作为value属性值,默认用数组值做value属性值
     * onclick -> 单击checkbox框触发什么函数 可为空
     * tagcss -> css名称 可为空
     * style -> style值, 可为空
     * <div class="checkbox i-checks">
     *      <label><input type="checkbox" value="" disabled="" checked=""> <i></i> 选项3（选中并禁用）</label>
     * </div>
     */
    public static function checkboxHtmlAttr ($checkboxArr, $tag_name, $val_value = true, $onclick = '', $tag_css = '', $tag_style = '', $checkedArr = Array(), $new_line = 10) {

        $tpl = $return = '';

        if ($onclick) {
            $tpl .= ' onclick="return '.$onclick.';"';
        }
        if ($tag_css) {
            $tpl .= ' class="'.$tag_css.'"';
        }
        if ($tag_style) {
            $tpl .= ' style="'.$tag_style.'"';
        }
        $tpl .= '/>';
        $i = 1;
        if ($val_value === true) {
            foreach ($checkboxArr as $key => $val) {
                $val = strip_tags($val);
                if (in_array($val, $checkedArr)) {
                    $checked = 'checked="checked"';
                } else {
                    $checked = '';
                }
                $return .= '<p><input type="checkbox" name="'.$tag_name.'[]" id="'.$tag_name.$i.'" '.$checked.' value="'.$val.'" '.$tpl.'&nbsp<label for="'.$tag_name.$i.'">'.$val.'</label></p>&nbsp;&nbsp;';
                if ($i % $new_line == 0) {
                    $return .= '<br />';
                }
                $i++;
            }
        } else {
            foreach ($checkboxArr as $key => $val) {
                $val = strip_tags($val);
                if (in_array($key, $checkedArr)) {
                    $checked = 'checked="checked"';
                } else {
                    $checked = '';
                }
                $return .= '<p><input type="checkbox" name="'.$tag_name.'['.$key.']" id="'.$tag_name.$key.'" '.$checked.' value="'.$key.'" '.$tpl.'&nbsp<label for="'.$tag_name.$key.'">'.$val.'</label></p>';
                if ($i % $new_line == 0) {
                    $return .= '<br />';
                }
                $i++;
            }
        }
        return $return;
    }

    /**
     * 过滤SQL注入攻击字符串
     *
     * @param string $str 检测是否是一个 1,32,23,3 这样的字符串
     * @return string
     */
    public static function sqlId($str) {
        if (preg_match('/^[1-9]\d{0,7}(,[1-9]\d{0,7})*$/', $str)){
            return True;
        }
        return False;
    }

    /**
     * 转换给前段使用
     * @param $data
     * @return array
     */
    public static function arrayToKeyVal($data) {
        $result = [];
        foreach ($data as $key => $val) {
            if (!is_array($val)) {
                $arrTmp = [];
                $arrTmp['id'] = $key;
                $arrTmp['val'] = $val;
                $result[] = $arrTmp;
            } else {
                $result[$key] = self::arrayToKeyVal($val);
            }
        }
        return $result;
    }

    /**
     * makeDir
     *
     * 自动建立文件夹
     * $dir 要建立文件夹的相对路径
     * $rootDir 应用程序的绝对路径
     */
    public static function makeDir($dir, $rootDir) {

        $dir = $rootDir . $dir;
        $separator = (DIRECTORY_SEPARATOR == '/') ? '\\' : '/';
        $dir = str_replace($separator, DIRECTORY_SEPARATOR, $dir);
        $tdir = str_replace($separator, DIRECTORY_SEPARATOR, $rootDir);

        if (substr($dir, -1) != DIRECTORY_SEPARATOR) {
            $dir = dirname($dir);
        }

        if (!file_exists($dir)) {
            $dir = substr($dir, strlen($rootDir));
            $dirs = explode(DIRECTORY_SEPARATOR, $dir);

            foreach ($dirs as $dir) {
                $tdir .= $dir . DIRECTORY_SEPARATOR;
                if (!file_exists($tdir)) {
                    if (!mkdir($tdir, 0777)) {
                        return false;
                    }
                }
            }
        }

        return(true);
    }

    /**
     * @param       $data
     * @param array $allow
     * @param array $deny
     * @return mixed
     */
    public static function arrayField($data, $allow = array(), $deny = array()) {
        if (!empty($data)) {
            foreach ($data as $key => &$record) {
                if (is_array($record)) {
                    foreach ($record as $tkey => $val) {
                        if (count($allow) && !in_array($tkey, $allow)) {
                            unset($record[$tkey]);
                        }
                        if (count($deny) && in_array($tkey, $deny)) {
                            unset($record[$tkey]);
                        }
                    }
                } else {
                    if (count($allow) && !in_array($key, $allow)) {
                        unset($data[$key]);
                    }
                    if (count($deny) && in_array($key, $deny)) {
                        unset($data[$key]);
                    }
                }
            }
        }
        return $data;
    }

    /**
     * 返回key=>val映射
     * @param $data
     * @param $key
     * @param $val
     * @return array
     */
    public static function arrayMapByKey($data, $key = 'id', $val = '') {
        $result = Array();
        if (!empty($data)) {
            foreach ($data as $record) {
                if (empty($val)) {
                    $result[$record[$key]] = $record;
                } else {
                    $result[$record[$key]] = $record[$val];
                }
            }
        }
        return $result;
    }

    /**
     * 传递一个二维数组进来,然后返回这个数组的ID，用于解决单表查询关联其他表的信息
     * @param $data
     * @param string $key0
     * @param string $key1
     * @param string $key2
     * @param string $key3
     * @param string $key4
     * @return array
     */
    public static function returnArrayVal($data, $key0 = '', $key1 = '', $key2 = '', $key3 = '', $key4 = '') {
        $result = [];
        if (is_array($data)) {
            foreach ($data as $record) {
                if ($key0 && isset($record[$key0]) && intval($record[$key0])) {
                    $result[] = intval($record[$key0]);
                }
                if ($key1 && isset($record[$key1])  && intval($record[$key1])) {
                    $result[] = intval($record[$key1]);
                }
                if ($key2 && isset($record[$key2])  && intval($record[$key2])) {
                    $result[] = intval($record[$key2]);
                }
                if ($key3 && isset($record[$key3])  && intval($record[$key3])) {
                    $result[] = intval($record[$key3]);
                }
                if ($key4 && isset($record[$key4])  && intval($record[$key4])) {
                    $result[] = intval($record[$key4]);
                }
            }
            foreach ($result as $key => $val) {
                if (is_array($val)) {
                    $result[$key] = array_unique($val);
                }
            }
        }
        return array_unique($result);
    }

    /**
     * 移除为null的元素
     * @param $data
     * @return mixed
     */
    public static function removeNull($data, $zero = true) {
        foreach ($data as $key => $val) {
            if ($val === NULL) {
                unset($data[$key]);
            }
            if ($zero && $val == 0) {
                unset($data[$key]);
            }
        }
        return $data;
    }

    /**
     * 将无限分类进行分级别,设定lv值
     * @param $primary
     * @param $arr
     * @param array $arr2
     * @param int $perId
     * @param int $lv
     */
    public static function rLevel($primary, $arr, &$arr2 = Array(), $perId = 0, $lv=0) {
        if (!empty($arr)) {
            foreach ($arr as $value) {
                if (isset($value['parent_id']) && $value['parent_id'] == $perId) {
                    $value['lv'] = $lv;
                    $arr2[$value[$primary]] = $value;
                    $lv++;
                    self::rLevel($primary, $arr, $arr2, $value[$primary], $lv--);
                }
            }
        }
    }

    /**
     * 返回订单号
     * @param int $len
     * @return string
     */
    public static function sn($len = 17) {
        $salt = self::random($len - 15, 1);
        $year = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J','K','M','N','P','R','S','T','U','V','W','X','Y','Z');
        return $year[intval(date('Y')) - 2017] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . $salt;
    }

    /**
     * @param     $length
     * @param int $numeric
     * @return string
     */
    public static function random($length, $numeric = 0) {
        PHP_VERSION < '4.2.0' ? mt_srand((double)microtime() * 1000000) : mt_srand();
        $seed = base_convert(md5(print_r($_SERVER, 1).microtime()), 16, $numeric ? 10 : 35);
        $seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
        $hash = '';
        $max = strlen($seed) - 1;
        for($i = 0; $i < $length; $i++) {
            $hash .= $seed[mt_rand(0, $max)];
        }
        return $hash;
    }

    /**
     * 无线分类进行重构
     * @param $primary
     * @param $input
     * @param array $output
     * @param int $perId
     */
    public static function refactor($primary, $input, &$output = Array(), $perId = 0) {
        if ((bool)$input) {
            $check = False;
            foreach ($input as $key => $val) {
                if ((isset($val['parent_id']) && $val['parent_id'] == $perId)) {
                    $check = True;
                    $output[$val[$primary]] = $val;
                    self::refactor($primary, $input, $output[$val[$primary]]['sub'], $val[$primary]);
                }
            }
            if (!$check) {
                $output = null; //this node have not child
            }
        }
    }

    /**
     * 无限分类进行重构,no key
     * @param $primary
     * @param $input
     * @param array $output
     * @param int $perId
     */
    public static function refactorNoKey($primary, $input, &$output = Array(), $perId = 0) {
        if ((bool)$input) {
            $check = False;
            foreach ($input as $key => $val) {
                if (isset($val['parent_id']) && $val['parent_id'] == $perId) {
                    $check = True;
                    $output[] = $val;
                    $key = key($output);
                    next($output);
                    self::refactorNoKey($primary, $input, $output[$key]['sub'], $val[$primary]);
                }
            }
            if (!$check) {
                $output = []; //this node have not child
            }
        }
    }

    public static function cutword($str, $len, $suffix = '', $start = 0) {

        $osLen = mb_strlen($str);

        $string = mb_substr($str, $start, $len, 'utf8');
        $sLen = mb_strlen($string,'utf8');
        $bLen = strlen($string);
        $sCharCount = (3 * $sLen-$bLen)/2;

        if ($osLen <= $sCharCount+$len) {
            $arr = preg_split('/(?<!^)(?!$)/u', mb_substr($str, $len+1, $osLen, 'utf8'));
        } else {
            $arr = preg_split('/(?<!^)(?!$)/u', mb_substr($str, $len, $sCharCount, 'utf8'));
        }

        foreach ($arr as $value) {
            if (ord($value) <128 && ord($value)>0) {
                $sCharCount = $sCharCount-1;
            } else {
                $sCharCount = $sCharCount-2;
            }
            if ($sCharCount <= 0) {
                break;
            }
            $string .= $value;
        }

        if ($osLen > $len) {
            $string .= $suffix;
        }

        return $string;

    }

    public static function cutstr($str, $start=0, $length, $suffix = '', $charset = 'UTF-8') {
        if ($suffix && mb_strlen($str, $charset) > $length) {
            return mb_substr($str, $start, $length, $charset) . $suffix;
        } else {
            return mb_substr($str, $start, $length, $charset);
        }
    }

    /**
     * 图片圆形
     * @param $source
     * @param $target
     * @return resource
     */
    public static function createRoundImg($source, $target) {
        $resource = imagecreatefromstring(file_get_contents($source));
        $w = imagesx($resource);$h = imagesy($resource);
        $w = $h = min($w, $h);
        $img = imagecreatetruecolor($w, $h);
        //这一句一定要有
        imagesavealpha($img, true);
        //拾取一个完全透明的颜色,最后一个参数127为全透明
        $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
        imagefill($img, 0, 0, $bg);
        $r   = $w / 2; //圆半径
        for ($x = 0; $x < $w; $x++) {
            for ($y = 0; $y < $h; $y++) {
                $rgbColor = imagecolorat($resource, $x, $y);
                if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }
        //返回资源
        if (!$target) return $img;
        //输出图片到文件
        imagepng ($img, $target);
        //释放空间
        imagedestroy($resource);
        //释放资源
        imagedestroy($img);
    }

    /**
     * 检测一个变量是否为空
     * @param $value
     * @return bool
     */
    public static function isEmpty($value){
        return (empty($value) || $value=="");
    }

    /**
     * 是否包含空白、控制字符
     * @param $value
     * @return mixed
     */
    public static function isSpace($value){
        return preg_match( '/[\s\a\f\n\e\0\r\t\x0B]/is', $value);
    }


    /**
     * email地址合法性检测
     * @param $value
     * @return mixed
     */
    public static function isEmail($value){
        return preg_match("/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $value);
        //return preg_match ( '/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,4})(\]?)$/', $value )
    }

    /**
     * URL地址合法性检测
     * @param $value
     * @return mixed
     */
    public static function isUrl($value){
        return preg_match("/^http:\/\/[\w]+\.[\w]+[\S]*/", $value);
    }

    /**
     * 是否是一个合法域名
     * @param $str
     * @return mixed
     */
    public static function isDomainName($str){
        return preg_match("/^[a-z0-9]([a-z0-9-]+\.){1,4}[a-z]{2,5}$/i", $str);
    }

    /**
     * 检测IP地址是否合法
     * @param $ip
     * @return mixed
     */
    public static function isIpAddr($ip){
        return preg_match("/^[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}$/", $ip);
    }

    /**
     * 邮编合法性检测
     * @param $value
     * @return bool
     */
    public static function isPostalCode($value){
        return (is_numeric($value) && (strlen($value)==6));
    }

    /**
     * 电话(传真)号码合法性检测
     */
    public static function isPhone($value){
        return preg_match("/^[\d]{3,4}-[\d]{7,8}$/", $value);
        //return preg_match ( "/^\d{11}$|^\d{3}-\d{7,8}$|^\d{4}-\d{7,8}$/", $tel );
    }

    /**
     * 手机号码合法性检查
     * @param $str
     * @return mixed
     */
    public static function isMobile($str){
        return preg_match("/^(1[345789])\d{9}$/i", $str);
    }

    /**
     * 身份证号码合法性检测
     * @param $value
     * @return mixed
     */
    public static function isIdCard($value){
        return preg_match("/^(\d{17}[\dx])$/i", $value);
    }

    /**
     * 严格的身份证号码合法性检测(按照身份证生成算法进行检查)
     * @param $value
     * @return bool
     */
    public static function chkIdCard($value){
        if (strlen($value) != 18){
            return false;
        }
        $wi = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
        $ai = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
        $value = strtoupper($value);
        $sigma = '';
        for ($i = 0; $i < 17; $i++) {
            $sigma += ((int) $value{$i}) * $wi[$i];
        }
        $parity_bit = $ai[($sigma % 11)];
        if ($parity_bit != substr($value, -1)){
            return false;
        }
        return true;
    }
}